Skip to content

Conversation

@cderv
Copy link
Collaborator

@cderv cderv commented Jan 28, 2026

When re-rendering a file during quarto preview in a project, the preview crashes with BadResource: Bad resource ID from the Sass cache Deno.Kv operations.

Root Cause

This is a regression from #13804 which changed how ProjectContext is managed during preview. That PR made the project context persist across re-renders (instead of being recreated each time), but renderForPreview() still called renderResult.context.cleanup() after each render.

The cleanup closes shared resources like the SassCache Deno.Kv handle. On subsequent re-renders, the code returns the cached SassCache instance whose KV handle was already closed, causing the BadResource error when calling kv.get().

Fix

  1. Remove the cleanup() call from renderForPreview() - the project context is owned by preview() and should only be cleaned up when preview exits via onCleanup()

  2. Invalidate the fileInformationCache entry for the rendered file before each render - since cleanup() previously cleared all caches (including fileInformationCache), removing the call means stale file content would be reused. The cache entry for the specific file being rendered is now deleted so changes are picked up.

Fixes #13955

@posit-snyk-bot
Copy link
Collaborator

posit-snyk-bot commented Jan 28, 2026

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This normalization is related to

Windows / Linux and Project vs Single file leads to different paths. I tried to make that works because we need to delete by key, so it is important to get the right path, but obviously this modify current behavior, and leads to failed test.

@cderv
Copy link
Collaborator Author

cderv commented Jan 29, 2026

😞 I tried to preview quarto-web with this PR, and I still encounter some issue with sass Kv, we may have an other issue.

@cderv
Copy link
Collaborator Author

cderv commented Jan 29, 2026

Ok so I don't manage to reproduce, maybe it was a bad state. quarto preview on quarto-web works ok to navigate;

However, as expected, change .scss file for example does trigger re-render, but the change are not shown. Though I am really not even sure this working with current 1.8 as discussed.

However, testing quarto render on a single doc, no project fails to udpate.

And I am quite convinced this is because of this normalize path key. So not good to merge yet

  • Quarto Project => quarto preview works
  • Single file => quarto preview does not show change in output file.

@cderv
Copy link
Collaborator Author

cderv commented Jan 29, 2026

🤦 It is late for me and I spent much time of this, now this should really be non-normalized path for lookup.

I'll test tomorrow manually the behavior

@cderv
Copy link
Collaborator Author

cderv commented Jan 30, 2026

So the normalizing is done correctly this time. All tests passes. I am currently checking other preview features and we're good!

@cderv
Copy link
Collaborator Author

cderv commented Jan 30, 2026

Manual Testing Summary

Tested using Claude Code with Chrome DevTools MCP to verify live browser updates.

Test Matrix

Scenario Code Path Result
Project context (with _quarto.yml) renderProject
Single file (no _quarto.yml) singleFileProjectContext
RevealJS format Different output handling

Detailed Results

Input file types tested:

  • .qmd files ✅
  • .md files ✅
  • .ipynb files ✅

Resource files tested:

  • .scss custom styles ✅
  • .lua filters ✅
  • Image files ⚠️ (reload only, no re-render - expected)

Stress tests:

  • Rapid edits (5+ quick saves) ✅
  • Stop and restart preview ✅

Key Finding

No BadResource errors across 15+ render cycles in all scenarios.

Pre-existing Issues Found (NOT regressions)

These were verified against baseline 1.9.17 - same behavior:

  • Partial files ({{< include _partial.qmd >}}) not watched
  • _quarto.yml changes not detected

@cderv cderv marked this pull request as ready for review January 30, 2026 17:49
@cderv cderv requested a review from cscheid January 30, 2026 17:50
@cderv
Copy link
Collaborator Author

cderv commented Jan 30, 2026

Yeah all tests passes with latest change too. If this is good TS change, then we can merge and build the next prerelease !

Copy link
Collaborator

@cscheid cscheid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great 🚀

cderv added 4 commits January 30, 2026 20:11
…t each render in preview mode

the project context is owned by `preview()` and cleaned up when preview exits. Calling `cleanup()`  here would close shared resources (like SassCache KV handles) causing BadResource errors on subsequent re-renders (#13955).
… ensure changes are picked up in preview mode
@cderv
Copy link
Collaborator Author

cderv commented Jan 30, 2026

Thank you. I'll clean the branch and merge

cderv and others added 7 commits January 30, 2026 20:17
Documents the project context lifecycle fix from #13804 that resolves
intermittent preview crashes when editing notebooks and qmd files.
and add a debug log message when we do so.
The fileInformationCache was using inconsistent path formats as keys,
causing cache misses during preview. On Windows, paths could be stored
with forward slashes but looked up with backslashes (or vice versa).

Apply normalizePath() at all cache access points:
- ensureFileInformationCache() in project-shared.ts (entry point)
- renderForPreview() deletion in preview.ts
- populateFileInformation() and inspectDocumentConfig() in inspect.ts
- cleanupNotebook() in jupyter.ts

Add unit tests for fileInformationCache behavior with reusable
createMockProjectContext() factory in tests/unit/project/utils.ts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move normalization logic from call sites into the cache class itself.
The class now overrides get/has/set/delete to normalize keys automatically,
ensuring consistent cache behavior without requiring callers to remember
to normalize paths.

Also fix ensureFileInformationCache fallback to create FileInformationCacheMap
(not plain Map) and add test coverage for this case.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@cderv cderv merged commit 0ff33a3 into main Jan 30, 2026
51 checks passed
@cderv cderv deleted the fix/issue-13955 branch January 30, 2026 20:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BadResource error during preview re-render

4 participants